package com.whosly.strategy.registrar.container;

import com.google.common.collect.Sets;
import com.whosly.scanner.Scanner;
import com.whosly.scanner.api.IScanner;
import com.whosly.scanner.config.ScanConfig;
import com.whosly.strategy.container.IStrategyContainer;
import com.whosly.strategy.registrar.AbstractBeanDefinitionRegistrar;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.support.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.annotation.AnnotationAttributes;

import java.util.*;

/**
 * ContainerRegistrar 与 ContainerSpringRegistrar 二选一
 *
 * @Author yueny09 <deep_blue_yang@126.com>
 * @Date 2019-09-04 14:22
 */
@DependsOn("manageSpringBeans")
public class ContainerRegistrar extends AbstractBeanDefinitionRegistrar {
    private IScanner scanner = new Scanner();

    private static List<Class<?>> containerList = new ArrayList<>();

    @Override
    protected String getTaskName(){
        return "ContainerRegistrar";
    }

    @Override
    protected void registerBeanDefinitions(AnnotationAttributes enableStrategy, BeanDefinitionRegistry registry) {
        String[] basePackages = enableStrategy.getStringArray("value");
        if(basePackages == null || basePackages.length == 0){
            containerList = getContainer(Sets.newHashSet(BASE_PACKAGES));
        }else{
            containerList = getContainer(Sets.newHashSet(basePackages));
        }
    }

    private List<Class<?>> getContainer(Set<String> basePackages) {
        List<Class<?>> list = scanner.scan(
            basePackages, IStrategyContainer.class, Arrays.asList(ScanConfig.ClazzType.INTERFACE));

        return list;
    }

    /**
     * 在容器初始化完成后，添加bean
     *
     * AfterRegistrar 注入顺序晚于 ManageSpringBeans(<code>StrategyConfigurationSelector</code>)， 所以 ManageSpringBeans 比 AfterRegistrar 先实例化
     */
    public static class AfterRegistrar implements ApplicationContextAware, InitializingBean {
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            if(containerList == null || containerList.isEmpty()){
                return;
            }

            DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext
                    .getAutowireCapableBeanFactory();
            for (Class<?> containerBean: containerList) {
                // TODO
                //this.registerBean(beanFactory, containerBean.getName(), containerBean);
            }

            if(containerList == null || containerList.isEmpty()){
                containerList.clear();
            }
        }

        /**
         *  容器初始化完成后进行添加bean
         *
         * @param beanClass
         */
        private void registerBean(DefaultListableBeanFactory beanFactory, String beanName, Class<?> beanClass) {
            AnnotatedBeanDefinition annotatedBeanDefinition = new AnnotatedGenericBeanDefinition(beanClass);
            beanFactory.registerBeanDefinition(beanName,annotatedBeanDefinition);
        }

        @Override
        public void afterPropertiesSet() throws Exception {
            //.
        }
    }

}
